home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / clang / nn.zip / COLLECT.C < prev    next >
C/C++ Source or Header  |  1989-12-31  |  7KB  |  320 lines

  1. #include "config.h"
  2. #include "db.h"
  3. #include "news.h"
  4.  
  5. #define COUNT_RE_REFERENCES    /* no of >>> depends on Reference: line */
  6.  
  7. export int ignore_bad_articles = 1;    /* no Newsgroups: line */
  8. export int remove_bad_articles = 0;
  9.  
  10. import int trace;
  11.  
  12.  
  13. static FILE *ix, *data;
  14.  
  15. /*
  16.  *    Collect unread articles in current group
  17.  *
  18.  *    On entry, init_group has been called to setup the proper environment
  19.  */
  20.  
  21. long collect_group(gh)
  22. register group_header *gh;
  23. {
  24.     long article_count, temp;
  25.     article_number start_collect;
  26.     
  27.     if (gh->last_l_article == 0) {
  28.     gh->first_l_article = gh->first_article;
  29.     gh->last_l_article = gh->first_l_article - 1;
  30.     }
  31.  
  32.     if (gh->last_l_article >= gh->last_article) return 0;
  33.     
  34.     if (gh->index_write_offset) {
  35.     ix = open_data_file(gh, 'x', OPEN_UPDATE|MUST_EXIST);
  36.     fseek(ix, gh->index_write_offset, 0);
  37.     } else
  38.         ix = open_data_file(gh, 'x', OPEN_CREATE|MUST_EXIST);
  39.  
  40.     if (gh->data_write_offset) {
  41.     data = open_data_file(gh, 'd', OPEN_UPDATE|MUST_EXIST);
  42.     fseek(data, gh->data_write_offset, 0);
  43.     } else
  44.     data = open_data_file(gh, 'd', OPEN_CREATE|MUST_EXIST);
  45.  
  46.     article_count = 0;
  47.     start_collect = gh->last_l_article+1;
  48.     
  49.     while (gh->last_l_article < gh->last_article) {
  50.     if (s_hangup) break;
  51.     gh->last_l_article++;
  52.     gh->data_write_offset = ftell(data);
  53. #ifdef NNTP
  54.     gh->index_write_offset = ftell(ix);
  55. #endif
  56.     if (!db_write_offset(ix, &(gh->data_write_offset)))
  57.         write_error();
  58.  
  59.     temp = collect_article(gh, gh->last_l_article);
  60. #ifdef NNTP
  61.     if (temp < 0) {
  62.         /* connection failed, current article is not collected */
  63.         gh->last_l_article--;
  64.         article_count = -1;
  65.         goto out;
  66.     }
  67. #endif    
  68.     article_count += temp;
  69.     }
  70.  
  71.     if (trace && start_collect <= gh->last_l_article) {
  72.     log_entry('T', "Col %s (%d to %d) %d", 
  73.           gh->group_name, 
  74.           start_collect, gh->last_l_article,
  75.           article_count);
  76.     fl;
  77.     }
  78.     
  79.     gh->data_write_offset = ftell(data);
  80.     gh->index_write_offset = ftell(ix);
  81.  
  82.  out:
  83.     fclose(data);
  84.     fclose(ix);
  85.     
  86.     return article_count;
  87. }
  88.  
  89.  
  90. static data_header hdr;
  91.  
  92.  
  93. static collect_article(gh, art_num)
  94. register group_header *gh;
  95. article_number art_num;
  96. {
  97.     FILE *art_file;
  98.     news_header_buffer nhbuf, dgbuf;
  99.     article_header art_hdr;
  100.     int mode, count;
  101.     cross_post_number cross_post_table[256], *cp_ptr;
  102.     count = 0;
  103.     
  104.     hdr.dh_number = art_num;
  105.     
  106.     /* get article header */
  107.  
  108.     art_hdr.a_number = art_num;
  109.     art_hdr.hpos = (off_t)0;
  110.     art_hdr.lpos = (off_t)0;
  111.     art_hdr.flag = 0;
  112.     
  113.     mode = FILL_NEWS_HEADER | FILL_OFFSETS | SKIP_HEADER; 
  114.     if ((gh->group_flag & (G_CONTROL | G_NEVER_DIGEST | G_ALWAYS_DIGEST)) == 0)
  115.     mode |= DIGEST_CHECK;
  116.     
  117.     if ((art_file = open_news_article(&art_hdr, mode, nhbuf, (char *)NULL)) == NULL) {
  118.  
  119. #ifdef NNTP
  120.     import nntp_failed;
  121.     
  122.     if (nntp_failed) {
  123.         /* 
  124.          * connection to nntp_server is broken 
  125.          * stop collection of articles immediately
  126.          */
  127.         return -1;
  128.     }
  129. #endif    
  130.     /* 
  131.      * it is not really necessary to save anything in the data file
  132.      * we simply use the index file to get the *first* available article
  133.      */
  134.     return 0;
  135.     }
  136.  
  137.     if (ignore_bad_articles && news.ng_groups == NULL) {
  138.     char *rem = "";
  139.     
  140. #ifndef NNTP
  141.     if (remove_bad_articles) {
  142.         unlink(group_path_name);
  143.         rem = "removed ";
  144.     }
  145. #endif NNTP
  146.     log_entry('B', "%sbad article: %s/%ld", rem, 
  147.           current_group->group_name, (long)art_num);
  148.     return 0;
  149.     }
  150.  
  151.     /* map cross-postings into a list of group numbers */
  152.  
  153.     hdr.dh_cross_postings = 0;
  154.     
  155.     if (gh->group_flag & G_CONTROL) {
  156.     /* we cannot trust the Newsgroups: line in the control group */
  157.     /* so we simply ignore it (i.e. use "Newsgroups: control") */
  158.     goto dont_digest;
  159.     }
  160.  
  161.     if (news.ng_groups) {
  162.     char *curg, *nextg;
  163.     group_header *gh1;
  164.     
  165.     for (nextg = news.ng_groups, cp_ptr = cross_post_table; *nextg; ) {
  166.         curg = nextg;
  167.         
  168.         if (nextg = strchr(curg, ','))
  169.         *nextg++ = NUL;
  170.         else
  171.         nextg = "";
  172.         
  173.         if (strcmp(gh->group_name, curg) == 0) /* break; */
  174.         gh1 = gh;
  175.         else
  176.         if ((gh1 = lookup(curg)) == NULL) continue;
  177.  
  178.         *cp_ptr++ = gh1->group_num;
  179.         hdr.dh_cross_postings++;
  180.     }
  181.     }
  182.     
  183.     if (gh->group_flag & G_NEVER_DIGEST)
  184.     goto dont_digest;
  185.  
  186.     /* split digest */
  187.  
  188.     
  189.     if ((gh->group_flag & G_ALWAYS_DIGEST) || (news.ng_flag & N_DIGEST)) {
  190.     int any = 0, cont = 1;
  191.     
  192.     skip_digest_body(art_file);
  193.         
  194.     while (cont && (cont = get_digest_article(art_file, dgbuf)) >= 0) {
  195.  
  196.         if (any == 0) {
  197.         /* write DIGEST_HEADER */
  198.         build_hdr(2, -art_num, cross_post_table);
  199.         count++;
  200.  
  201.         hdr.dh_cross_postings = 0;    /* no cross post in sub */
  202.         any++;
  203.         }
  204.         /* write SUB_DIGEST */
  205.         build_hdr(1, (article_number)0, (group_number *)NULL);
  206.         count++;
  207.     }
  208.  
  209.     if (any) goto finish;
  210.     }
  211.     
  212.     /* not a digest */
  213.  
  214.  dont_digest:
  215.  
  216.     build_hdr(0, art_num, cross_post_table);    /* normal article */
  217.     count++;
  218.     
  219. finish:    
  220.     
  221.     fclose(art_file);
  222.  
  223.     return count;
  224. }
  225.  
  226.  
  227. static build_hdr(use_digest, art_num, cross_post_table)
  228. int use_digest;
  229. article_number art_num;
  230. cross_post_number *cross_post_table;
  231. {
  232.     register char *name, *subj;
  233.     char name_buf[NAME_LENGTH+1], subj_buf[256];
  234.     int re;
  235.     
  236.     if (use_digest & 1) {
  237.     
  238.     name = digest.dg_from;
  239.     subj = digest.dg_subj;
  240.  
  241.     hdr.dh_lines = digest.dg_lines;
  242.  
  243.     hdr.dh_hpos = digest.dg_hpos;
  244.     hdr.dh_fpos = (int16)(digest.dg_fpos - hdr.dh_hpos);
  245.     hdr.dh_lpos = digest.dg_lpos;
  246.     
  247.     pack_date(&(hdr.dh_date),
  248.           digest.dg_date ? digest.dg_date : news.ng_date);
  249.     } else {
  250.     
  251.     if (!news.ng_from) news.ng_from = news.ng_reply;
  252.     
  253.     name = news.ng_from;
  254.     subj = news.ng_subj;
  255.     
  256.     hdr.dh_lines = news.ng_lines;
  257.     
  258.     hdr.dh_hpos = 0;
  259.     hdr.dh_fpos = (int16)(news.ng_fpos);
  260.     hdr.dh_lpos = news.ng_lpos;
  261.  
  262.     pack_date(&(hdr.dh_date), news.ng_date);
  263.     }
  264.     
  265.     hdr.dh_number = art_num;    
  266.  
  267.     /* pack name and write on .nn2 */
  268.  
  269.     if (name) {
  270.     hdr.dh_sender_length = pack_name(name_buf, name, NAME_LENGTH);
  271.     } else
  272.         hdr.dh_sender_length = 0;
  273.     
  274.     /* write subject line on .nn2 */
  275.  
  276.     hdr.dh_subject_length = pack_subject(subj_buf, subj, &re, 255);
  277. #ifdef COUNT_RE_REFERENCES
  278.     if (re) re = 0x80;
  279.     if (news.ng_ref) {
  280.     for (name = news.ng_ref; *name; name++) {
  281.         if ((re & 0x7f) == 0x7f) break;
  282.         if (*name == '<') re++;
  283.     }
  284.     }    
  285. #endif
  286.     hdr.dh_replies = re;
  287.  
  288.     if (use_digest & 2) hdr.dh_subject_length++;    /* @ */
  289.  
  290.     /* WRITE hdr, cross postings, name, subject */
  291.  
  292.     db_write_art(data, &hdr);
  293.  
  294.     if (cross_post_table && hdr.dh_cross_postings) {
  295. #ifdef NETWORK_DATABASE
  296. #ifndef NETWORK_BYTE_ORDER
  297.     int i;
  298.     
  299.     for (i = 0; i < hdr.dh_cross_postings; i++)
  300.         cross_post_table[i] = htonl(cross_post_table[i]);
  301. #endif
  302. #endif    
  303.     Fwrite((char *)cross_post_table, sizeof(cross_post_number), 
  304.            (int)hdr.dh_cross_postings, data);
  305.     }
  306.     
  307.     if (hdr.dh_sender_length)
  308.     Fwrite(name_buf, sizeof(char), (int)hdr.dh_sender_length, data);
  309.  
  310.     if (use_digest & 2) {
  311.     putc('@', data);
  312.     hdr.dh_subject_length--;
  313.     }
  314.     
  315.     if (hdr.dh_subject_length)
  316.     Fwrite(subj_buf, sizeof(char), (int)hdr.dh_subject_length, data);
  317.  
  318.     return;
  319. }
  320.